using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Logging;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form;
using Volo.Abp.ObjectMapping;

namespace CKY.AgentPlatform.Web.Pages.RateLimit
{
    public class IndexModel : AgentPlatformPageModel
    {
        private readonly RateLimitStatisticsService _statisticsService;
        private readonly DistributedCacheService _cacheService;
        private readonly RateLimitOptions _options;
        private readonly IObjectMapper _objectMapper;
        private readonly ILogger<IndexModel> _logger;

        public IndexModel(
            RateLimitStatisticsService statisticsService,
            DistributedCacheService cacheService,
            IOptions<RateLimitOptions> options,
            IObjectMapper objectMapper,
            ILogger<IndexModel> logger)
        {
            _statisticsService = statisticsService;
            _cacheService = cacheService;
            _options = options.Value;
            _objectMapper = objectMapper;
            _logger = logger;
        }

        [ViewData]
        public string PageTitle { get; set; }

        public RateLimitStatisticsDto Statistics { get; set; }
        public List<ActiveClientDto> ActiveClients { get; set; }
        public List<RateLimitEventDto> RecentEvents { get; set; }
        public List<EndpointStatisticDto> EndpointStatistics { get; set; }
        public RateLimitConfigDto Config { get; set; }

        public string SelectedClient { get; set; }
        public ClientRateLimitStatisticsDto ClientStatistics { get; set; }
        public DateTime? EventStartDate { get; set; }
        public DateTime? EventEndDate { get; set; }

        public IpWhitelistRequest WhitelistRequest { get; set; }

        public async Task OnGetAsync()
        {
            PageTitle = "限流管理";
            
            await LoadDataAsync();
        }

        public async Task<IActionResult> OnPostResetClientAsync(string clientIdentifier)
        {
            try
            {
                await _statisticsService.ResetClientRateLimitAsync(clientIdentifier);
                Notifications.Success($"客户端 {clientIdentifier} 的限流计数器已重置");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "重置客户端限流计数器失败");
                Notifications.Error("重置失败: " + ex.Message);
            }

            await LoadDataAsync();
            return Page();
        }

        public async Task<IActionResult> OnPostAddToWhitelistAsync()
        {
            try
            {
                await _statisticsService.AddToIpWhitelistAsync(WhitelistRequest.IpAddress);
                Notifications.Success($"IP地址 {WhitelistRequest.IpAddress} 已添加到白名单");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "添加IP到白名单失败");
                Notifications.Error("添加失败: " + ex.Message);
            }

            await LoadDataAsync();
            return Page();
        }

        public async Task<IActionResult> OnPostRemoveFromWhitelistAsync(string ipAddress)
        {
            try
            {
                await _statisticsService.RemoveFromIpWhitelistAsync(ipAddress);
                Notifications.Success($"IP地址 {ipAddress} 已从白名单中移除");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "从白名单中移除IP失败");
                Notifications.Error("移除失败: " + ex.Message);
            }

            await LoadDataAsync();
            return Page();
        }

        public async Task<IActionResult> OnPostViewClientStatisticsAsync(string clientIdentifier)
        {
            SelectedClient = clientIdentifier;
            await LoadDataAsync();
            return Page();
        }

        public async Task<IActionResult> OnPostSearchEventsAsync()
        {
            await LoadDataAsync();
            return Page();
        }

        public async Task<IActionResult> OnPostCleanupAsync()
        {
            try
            {
                await _statisticsService.CleanupExpiredStatisticsAsync();
                Notifications.Success("过期统计数据已清理");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "清理过期统计数据失败");
                Notifications.Error("清理失败: " + ex.Message);
            }

            await LoadDataAsync();
            return Page();
        }

        private async Task LoadDataAsync()
        {
            try
            {
                // 加载统计信息
                var statistics = await _statisticsService.GetStatisticsAsync();
                Statistics = _objectMapper.Map<RateLimitStatistics, RateLimitStatisticsDto>(statistics);

                // 加载活跃客户端
                ActiveClients = await GetActiveClientsAsync();

                // 加载最近事件
                RecentEvents = await GetRecentEventsAsync();

                // 加载端点统计
                EndpointStatistics = _objectMapper.Map<List<EndpointStatistic>, List<EndpointStatisticDto>>(
                    statistics.TopEndpoints ?? new List<EndpointStatistic>());

                // 加载配置
                Config = _objectMapper.Map<RateLimitOptions, RateLimitConfigDto>(_options);
                var whitelistKey = "rate_limit:config:ip_whitelist";
                var cachedWhitelist = await _cacheService.GetAsync<List<string>>(whitelistKey);
                Config.IPWhitelist = cachedWhitelist ?? Config.IPWhitelist;

                // 加载客户端统计
                if (!string.IsNullOrEmpty(SelectedClient))
                {
                    var clientStats = await _statisticsService.GetClientStatisticsAsync(SelectedClient);
                    ClientStatistics = _objectMapper.Map<ClientRateLimitStatistics, ClientRateLimitStatisticsDto>(clientStats);
                }

                // 初始化请求对象
                WhitelistRequest = new IpWhitelistRequest();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "加载限流数据失败");
                Notifications.Error("加载数据失败: " + ex.Message);
            }
        }

        private async Task<List<ActiveClientDto>> GetActiveClientsAsync()
        {
            var clients = new List<ActiveClientDto>();
            
            try
            {
                var activeKey = $"rate_limit:active:{DateTime.UtcNow:yyyy-MM-dd-HH}";
                var activeClientKeys = await _cacheService.GetAsync<List<string>>(activeKey) ?? new List<string>();

                foreach (var clientKey in activeClientKeys.Take(50))
                {
                    var clientInfo = await _cacheService.GetAsync<ClientInfo>($"rate_limit:client_info:{clientKey}");
                    if (clientInfo != null)
                    {
                        clients.Add(new ActiveClientDto
                        {
                            ClientIdentifier = clientKey,
                            IpAddress = clientInfo.IpAddress,
                            UserAgent = clientInfo.UserAgent,
                            LastRequest = clientInfo.LastRequest,
                            TotalRequests = clientInfo.TotalRequests
                        });
                    }
                }

                return clients.OrderByDescending(c => c.LastRequest).ToList();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取活跃客户端失败");
                return new List<ActiveClientDto>();
            }
        }

        private async Task<List<RateLimitEventDto>> GetRecentEventsAsync()
        {
            try
            {
                var startDate = EventStartDate ?? DateTime.UtcNow.AddDays(-1);
                var endDate = EventEndDate ?? DateTime.UtcNow;
                
                var events = await _statisticsService.GetRateLimitEventsAsync(startDate, endDate);
                return _objectMapper.Map<List<RateLimitEvent>, List<RateLimitEventDto>>(
                    events.Take(100).ToList());
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取限流事件失败");
                return new List<RateLimitEventDto>();
            }
        }
    }

    public class RateLimitStatisticsDto
    {
        public DateTime Timestamp { get; set; }
        public long TotalRequests { get; set; }
        public long BlockedRequests { get; set; }
        public int ActiveClients { get; set; }
        public double BlockRate { get; set; }
        public List<ClientStatisticDto> TopBlockedClients { get; set; }
        public List<EndpointStatisticDto> TopEndpoints { get; set; }
        public double ResponseTimeAverage { get; set; }
    }

    public class ClientStatisticDto
    {
        public string ClientIdentifier { get; set; }
        public long RequestCount { get; set; }
        public long BlockedCount { get; set; }
        public DateTime LastRequest { get; set; }
    }

    public class EndpointStatisticDto
    {
        public string EndpointKey { get; set; }
        public long RequestCount { get; set; }
        public long BlockedCount { get; set; }
        public double AverageResponseTime { get; set; }
    }

    public class RateLimitEventDto
    {
        public DateTime Timestamp { get; set; }
        public string ClientIdentifier { get; set; }
        public string EndpointKey { get; set; }
        public string Action { get; set; }
        public string Reason { get; set; }
        public string IpAddress { get; set; }
        public string UserAgent { get; set; }
    }

    public class RateLimitConfigDto
    {
        public bool EnableRateLimiting { get; set; }
        public int MaxRequests { get; set; }
        public int WindowMinutes { get; set; }
        public bool EnableApiKeyAuth { get; set; }
        public string ApiKeyHeaderName { get; set; }
        public string ApiKeyQueryParam { get; set; }
        public List<string> IPWhitelist { get; set; }
        public List<string> UserWhitelist { get; set; }
        public List<string> PathWhitelist { get; set; }
        public bool EnableLogging { get; set; }
        public bool EnableStatistics { get; set; }
    }

    public class ActiveClientDto
    {
        public string ClientIdentifier { get; set; }
        public string IpAddress { get; set; }
        public string UserAgent { get; set; }
        public DateTime LastRequest { get; set; }
        public long TotalRequests { get; set; }
    }

    public class ClientRateLimitStatisticsDto
    {
        public string ClientIdentifier { get; set; }
        public DateTime Timestamp { get; set; }
        public long TotalRequests { get; set; }
        public long BlockedRequests { get; set; }
        public int CurrentLimit { get; set; }
        public double BlockRate { get; set; }
        public List<string> Endpoints { get; set; }
    }

    public class IpWhitelistRequest
    {
        public string IpAddress { get; set; }
    }

    public class ClientInfo
    {
        public string IpAddress { get; set; }
        public string UserAgent { get; set; }
        public DateTime LastRequest { get; set; }
        public long TotalRequests { get; set; }
    }
}